home *** CD-ROM | disk | FTP | other *** search
- #include <stdlib.h>
- #include "outwin.h"
- #include "cursor.h"
- #include "global.h"
-
- loc get_param(char* str) // Read parameter for command and
- { // convert in to number
- int sh = strchr(str, ' ') - str; // f.e. in @FONT 1 .., 1 is parameter
- char ch[5]; memset(ch, '\0', 5);
- strncpy(ch, str, sh);
- return loc(atoi(ch), sh + 1);
- }
- ///////////////////////////
- int ret_count(char* s) // counts '\n' symbols in the string
- {
- char* c = s;
- int n;
- for(n = 0; c = strchr(c, '\n'); n++)
- c++;
- return n;
- }
- /////////////////////////
- OutputWindow::OutputWindow(rect coordinates, char* vName,
- int b_type, int s, int bak,
- int attr, int interv, int p_height)
- : Window(coordinates, "", "", s, (BORDERS)b_type)
-
- {
- end = 0;
- page = (char*)malloc(st_page_height * max_string_len);
- start = loc(0, 0);
- interval = interv;
- bak_color = bak;
- attr_color = attr;
- curs = loc(0, interval);
- viewName = strdup(vName);
- page_height = p_height;
- file_position = 0;
- pages = (long*)malloc(num_pages * sizeof(long) + 2);
- pages[0] = 1;
- pages[1] = 0;
- // contexts = (context*)malloc(MAXKEYS * sizeof(context)); // if another solutions does not work
- // new context()[MAXKEYS]; // for BC 2.0
- contexts = new context[MAXKEYS]; // for BC 3.0
-
- key_rects = new special[MAXKEYS];
- number = 0;
- load_file();
- }
- ////////////////////////
- OutputWindow::~OutputWindow()
- {
- delete pages;
- delete viewName;
- delete page;
- delete contexts;
- delete key_rects;
- }
- /////////////////////////
- void OutputWindow::show()
- {
- Window::show();
- load();
- view();
- mouseHideCursor();
- rect r = user_screen();
- curs = loc(0, interval);
- cursor.set_cursor(r.origin.X, r.origin.Y + interval);
- cursor.show_cursor();
- mouseShowCursor();
- }
- //////////////////////////
- void OutputWindow::mouse_curs(loc ms_pos)
- {
- rect r = user_screen();
- int x = ((ms_pos.X - r.origin.X) / pScreenSet->standart_width)
- * pScreenSet->standart_width;
- int y = ((ms_pos.Y - r.origin.Y) / interval + 1) * interval;
- if(!r.contains(rect(x + r.origin.X, y + r.origin.Y - interval,
- x + r.origin.X + pScreenSet->standart_width, y + r.origin.Y)))
- return ;
- curs = loc(x, y);
- }
-
- /////////////////////////
- void OutputWindow::view()
- {
- settextstyle(DEFAULT_FONT, HORIZ_DIR, 1);
- setusercharsize(1, 1, 1, 1);
- settextjustify(LEFT_TEXT, TOP_TEXT);
-
- rect r = user_screen();
- setviewport(r.origin.X, r.origin.Y, r.corner.X, r.corner.Y, 1);
-
- mouseHideCursor();
-
- curs = loc(1, interval);
-
- int num = ret_count(page);
- if(start.Y > num)
- start.Y = num;
-
- char* str = page;
- int count_ret = start.Y;
- loc skip(0, 0);
-
- setfillstyle(SOLID_FILL, bak_color);
- bar(0, 0, r.width(), r.height());
- char tm[max_string_len]; // max len
- int flag = start.X;
- int is_first = 0; // first pass - text, second - icons
-
- number = 0;
- while(1)
- {
- memset(tm, '\0', max_string_len);
- int i = 0;
- while(str[i] != '\n' && str[i] && str[i] != '@')
- { // @ - spec. symbol
- tm[i] = str[i];
- i++;
- }
-
- if(*tm && !count_ret && strlen(tm) > flag)
- {
- skip.X = (skip.X - flag > 0) ? (skip.X - flag) : 0;
- int real_skip = skip.X * textwidth(" ");
- curs.X += real_skip;
- if(!is_first)
- {
- bar(curs.X, curs.Y - interval + 1,
- curs.X + textwidth(tm + flag + skip.X), curs.Y);
- outtextat(loc(curs.X, curs.Y - interval + 1), tm + flag + skip.X);
- }
- curs.X += textwidth(tm + flag + skip.X);
- flag = 0; skip = loc(0, 0);
- }
- else flag -= strlen(tm);
-
- if(str[i] == '\n')
- {
- if(curs.Y + interval <= r.height())
- {
- i++; curs.X = 1; flag = start.X;
- if(count_ret > 0)
- count_ret--;
- else curs.Y += interval;
- skip = loc(0, 0); // !!!
- }
- else
- {
- if(is_first)
- break;
- else
- {
- is_first = 1;
- curs = loc(1, interval);
- str = page;
- count_ret = start.Y;
- skip = loc(0, 0);
- flag = start.X;
- continue;
- }
- }
- }
- switch(str[i])
- {
- case '@':
- char command[10];
- memset(command, '\0', 10);
- i++;
- char* c = strchr(str + i, ' ');
- int n = c - str - i;
- strncpy(command, str + i, n);
- i += n + 1;
- int fl = screenXL(flag);
- skip = process(str + i, command, fl, count_ret, is_first);
- i += skip.Y;
- break;
- }
-
- if(!str[i] || (curs.Y > r.height() + 1))
- {
- if(is_first)
- break;
- else
- {
- is_first = 1;
- curs = loc(1, interval);
- str = page;
- count_ret = start.Y;
- skip = loc(0, 0);
- flag = start.X;
- continue;
- }
- }
- str = str + i;
- }
- setviewport(0, 0, getmaxx(), getmaxy(), 1);
- mouseShowCursor();
- }
- ////////////////////////////
- void OutputWindow::exe(int act)
- {
- e.what = act ? KEYEVENT : NOEVENT;
- global_i[0] = action_type;
- switch(act)
- {
- case AC_LEFT: e.key = EVENT_LEFT; break;
- case AC_RIGHT: e.key = EVENT_RIGHT; break;
- case AC_UP: e.key = EVENT_UP; break;
- case AC_DOWN: e.key = EVENT_DN; break;
- case AC_PG_UP: e.key = EVENT_PG_UP; break;
- case AC_PG_DN: e.key = EVENT_PG_DN; break;
- case AC_HOME: e.key = EVENT_HOME; break;
- case AC_END: e.key = EVENT_END; break;
- case AC_CANCEL: e.key = (isRet(RET_REMOVE))
- ? EVENT_ALT_F3 : EVENT_ESC;
- break;
- case AC_OK: e.key = EVENT_F2; break;
- case AC_PREV: e.key = EVENT_ALT_F1; break;
- }
- rect r = user_screen();
- mouseHideCursor();
- if(!act)
- hilite();
- mouseShowCursor();
- while(1)
- {
- mouseShowCursor();
- if(!act)
- get_event();
- mouseHideCursor();
- if(e.what == KEYEVENT)
- switch(e.key)
- {
- case EVENT_ALT_F1: box_move(AC_PREV); break;
- case EVENT_RIGHT: box_move(AC_RIGHT); break;
- case EVENT_LEFT: box_move(AC_LEFT); break;
- case EVENT_UP: box_move(AC_UP); break;
- case EVENT_DN: box_move(AC_DOWN); break;
- case EVENT_HOME: box_move(AC_HOME); break;
- case EVENT_PG_UP: box_move(AC_PG_UP); break;
- case EVENT_END: box_move(AC_END); break;
- case EVENT_PG_DN: box_move(AC_PG_DN); break;
- case EVENT_CTRL_PG_UP: box_move(AC_CTRL_PG_UP); break;
-
- case EVENT_ESC: global_num = 0; unhilite();
- return;
- case EVENT_F6:
- case EVENT_F10:
- case EVENT_TAB:
- case EVENT_ALT_F3:
- case EVENT_ALT_F4:
- case EVENT_ALT_TAB:
- unhilite(); global_num = 0; return;
- case EVENT_F2:
- case EVENT_RETURN :
- if(!act)
- {
- box_move(AC_SELECT);
- break;
- }
- else
- {
- global_i[0] = action_type;
- global_num = 1;
- return;
- }
- case EVENT_ALT_P:
- // case EVENT_ALT_F:
- global_i[0] = action_type;
- global_num = 1;
- return;
- }
- else
- {
- mouseHideCursor();
- if(!mouse_in(loc(e.where()))) // outside of menu box
- {
- unhilite();
- global_num = 0;
- return;
- }
-
- cursor.hide_cursor();
- mouse_curs(loc(e.where()));
- cursor.set_cursor(r.origin.X + curs.X, r.origin.Y + curs.Y);
- cursor.show_cursor();
- mouseShowCursor();
-
- box_move(AC_SELECT);
- }
- if(act)
- return;
- }
- }
- ///////////////////////////
- loc OutputWindow::process(char* str, char* command, int flag, int count_ret,
- int is_first)
- {
- rect r = user_screen();
-
- if(!strcmp(command, "COLOR"))
- {
- int n = strchr(str, ' ') - str;
- char ch[5]; memset(ch, '\0', 5); strncpy(ch, str, n);
- int bak_new = atoi(ch);
- int m = strchr(str + n + 1, ' ') - str;
- memset(ch, '\0', 5); strncpy(ch, str + n + 1, m);
- int attr_new = atoi(ch);
- if(is_first)
- return loc(0, n + m);
- setfillstyle(SOLID_FILL, bak_new);
- setcolor(attr_new);
- return loc(0, n + m);
- }
- if(!strcmp(command, "RESET_COL"))
- {
- if(is_first)
- return loc(0, 0);
-
- setfillstyle(SOLID_FILL, bak_color);
- setcolor(attr_color);
- return loc(0, 0);
- }
- if(!strcmp(command, "FONT"))
- {
- int n = strchr(str, ' ') - str;
- char ch[5]; memset(ch, '\0', 5); strncpy(ch, str, n);
- int font_new = atoi(ch);
- int m = strchr(str + n + 1, ' ') - str;
- memset(ch, '\0', 5); strncpy(ch, str + n + 1, m);
- int size_new = atoi(ch);
- if(is_first)
- return loc(0, n + m);
-
- settextstyle(font_new, HORIZ_DIR, size_new);
- return loc(0, n + m);
- }
- if(!strcmp(command, "KEY"))
- {
- char ch[10];
- loc w = get_param(str);
- loc h = get_param(str + w.Y);
-
- int m = 8;
- memset(ch, '\0', 10); strncpy(ch, str + w.Y + h.Y + 1, m);
-
- if(is_first || count_ret)
- return loc(0, w.Y + h.Y + m + 2);
-
- key_add(loc(w.X, h.X), ch);
-
- return loc(0, w.Y + h.Y + m + 2);
- }
- if(!strcmp(command, "REVERSE"))
- {
- if(is_first)
- return loc(0, 0);
-
- int attr, bak;
- attr = getcolor();
- struct fillsettingstype fillinfo;
- getfillsettings(&fillinfo);
- bak = fillinfo.color;
- setcolor(bak); setfillstyle(SOLID_FILL, attr);
- return loc(0, 0);
- }
- if(!strcmp(command, "ICON")) // @ICON TYPE NUM
- {
- int n = strchr(str, ' ') - str;
- char ch[5]; memset(ch, '\0', 5); strncpy(ch, str, n);
- int icon_type = atoi(ch);
- int m = strchr(str + n + 1, ' ') - str;
- memset(ch, '\0', 5); strncpy(ch, str + n + 1, m);
- int icon_num = atoi(ch);
- if(!is_first)
- return loc(0, n + m);
- loc lt = loc(r.origin.X + curs.X - flag,
- r.origin.Y + curs.Y - interval - count_ret * interval);
- loc size = icon_size(icon_type);
-
- Icon* icon = new Icon(textLoc(lt), icon_num, icon_type,
- NO_BORDER);
- imageP im = (imageP)icon->extract();
- rect dest = rect(lt, lt + size - 1);
- put_image_correct(im, dest);
- delete im;
- delete icon;
-
- return loc(0, n + m);
- }
- if(!strcmp(command, "SKIP")) // spaces to skip
- {
- int n = strchr(str, ' ') - str;
- char ch[5]; memset(ch, '\0', 5); strncpy(ch, str, n);
- int skip = atoi(ch);
- return loc(skip, n);
- }
- return loc(0, 0); // loc.X - to skip, loc.Y - size of command argument
- }
- /////////////////////////////
- void OutputWindow::box_move(int act)
- {
- int sz;
- loc res;
- mouseHideCursor();
- rect r = user_screen();
- cursor.set_cursor(r.origin.X + curs.X, r.origin.Y + curs.Y);
- cursor.hide_cursor();
-
- switch(act)
- {
- case AC_SELECT:
- int c_num = on_special();
- if(c_num) // number of context + 1
- {
- c_num--;
- listed.add(loc(pages[0], start.Y));
- pages[0] = contexts[c_num].page;
- file_position = pages[pages[0]];
- start.Y = contexts[c_num].line;
- start.X = 0;
- load();
- view();
- curs = loc(0, interval);
- }
- break;
- case AC_PREV:
- loc prev = listed.remove();
- if(prev.X == 0) break; // at the top - no more prev. pages
- pages[0] = prev.X;
- start.Y = prev.Y;
- file_position = pages[pages[0]];
- load();
- view();
- curs = loc(0, interval);
- break;
- case AC_LEFT:
- sz = pScreenSet->standart_width;
- if(curs.X >= sz) { curs.X -= sz; }
- else if(start.X > 0)
- {
- res = curs;
- start.X -= 1;
- view();
- curs = res;
- }
- break;
- case AC_RIGHT:
- sz = pScreenSet->standart_width;
- if(curs.X < r.width() - interval) { curs.X += sz; }
- else
- {
- res = curs;
- start.X += 1;
- view();
- curs = res;
- }
- break;
- case AC_HOME:
- res.Y = curs.Y; start.X = 0; view(); curs = loc(0, res.Y); break;
- case AC_END:
- sz = r.width() / pScreenSet->standart_width;
- start.X += sz;
- res.Y = curs.Y;
- view();
- curs = loc(0, res.Y);
- break;
-
- case AC_UP:
- sz = interval;
- if(curs.Y > sz)
- {
- curs.Y -= sz;
- break;
- }
- if(start.Y > 0)
- {
- res = curs; start.Y -= 1;
- view(); curs = res;
- }
- else // if we must reload
- {
- if(pages[0] <= 1)
- break;
- start.Y = page_height / 2;
- pages[0]--;
- file_position = pages[pages[0]];
- load();
- res = curs;
- view();
- curs = res;
- }
- break;
- case AC_PG_UP:
- if(start.Y < r.height() / interval)
- {
- if(pages[0] <= 1)
- {
- if(start.Y > 0)
- {
- start.Y = 0;
- view();
- curs = loc(0, interval);
- }
- break;
- }
- start.Y += page_height / 2 - r.height() / interval;
- pages[0]--;
- file_position = pages[pages[0]];
- load();
- }
- else start.Y -= r.height() / interval;
- res = curs;
- view(); curs = res; break;
-
- case AC_DOWN:
- sz = interval;
- if(curs.Y < r.height() - interval)
- {
- curs.Y += sz;
- break;
- }
- if(start.Y + r.height() / interval < page_height - 1)
- {
- res = curs; start.Y += 1;
- view(); curs = res;
- }
- else
- {
- if(end) break;
- pages[0]++;
- file_position = pages[pages[0]];
- start.Y = page_height / 2 - r.height() / interval - 1;
- load(); res = curs;
- view(); curs = res;
- }
- break;
- case AC_PG_DN:
- sz = r.height() / interval;
- if(start.Y + 2 * sz >= page_height)
- {
- if(end) break;
- start.Y -= (page_height / 2 - sz);
- pages[0]++;
- file_position = pages[pages[0]];
- load();
- }
- else start.Y += sz;
- res = curs; view(); curs = res;
- break;
- case AC_CTRL_PG_UP:
- pages[0] = 1;
- file_position = pages[pages[0]];
- start = loc(0, 0);
- load(); view();
- curs = loc(0, interval);
- break;
- }
- cursor.set_cursor(r.origin.X + curs.X, r.origin.Y + curs.Y);
- cursor.show_cursor();
- mouseShowCursor();
- }
- //////////////////////////
- int OutputWindow::load()
- {
- memset(page, '\0', st_page_height * max_string_len);
- char str[max_string_len];
- FILE *fileptr;
- fileptr = fopen(viewName, "r");
- fseek(fileptr, pages[pages[0]], 0);
- fpos_t pos;
- end = 0;
- int half_count = 0;
- for(int i = 0; i < page_height; i++)
- {
- char* c;
- c = fgets(str, max_string_len - 1, fileptr);
- if(c[0] == '<') //context
- continue;
- if(!c)
- {
- end = 1;
- break;
- }
-
- strcpy(page + strlen(page), str);
- if(half_count == 0 && i >= page_height / 2)
- {
- fgetpos(fileptr, &pos);
- pages[pages[0] + 1] = pos; // beginning of the next half of page
- half_count = 1;
- }
- }
-
- fgetpos(fileptr, &pos);
- file_position = pos;
- pages[pages[0] + 2] = pos; // end of page
-
- fclose(fileptr);
- return end;
- }
- //////////////////////////
- void OutputWindow::load_file()
- {
- rect r = user_screen();
- FILE *fileptr;
- fileptr = fopen(viewName, "r");
- fpos_t pos;
- int hp = 0; int lines = 0; int page_num = 1;
- char str[max_string_len]; char* c;
- int max = MAXKEYS;
- while(1)
- {
- memset(str, '\0', 10);
- c = fgets(str, max_string_len - 1, fileptr);
- lines++;
- if(lines >= page_height / 2)
- {
- lines = 0;
- fgetpos(fileptr, &pos);
- pages[page_num + 1] = pos; // beginning of the next half of page
- page_num++;
- }
- if(!c)
- break;
- if (hp == max - 1)
- {
- contexts = (context*)realloc(contexts, MAXKEYS * sizeof(context));
- max = 0;
- }
- if (str[0] != '<')
- continue;
-
- strncpy(contexts[hp].cont_name, str + 1, 8);
- contexts[hp].cont_name[8] = '\0';
- contexts[hp].page = page_num;
- if(lines < page_height - r.height() / interval)
- contexts[hp].line = lines - 1;
- else
- contexts[hp].line = page_height - r.height() / interval;
- hp++;
- }
-
- fclose(fileptr);
- }
- /////////////////////////////
- void OutputWindow::key_add(loc wh, char* ch)
- {
- if(number > MAXKEYS - 1)
- key_rects = (special*)realloc(key_rects, MAXKEYS * sizeof(special));
-
- key_rects[number].ltrb = rect(curs.X, curs.Y - interval,
- curs.X + wh.X * pScreenSet->standart_width,
- curs.Y - interval + wh.Y * interval);
-
- strncpy(key_rects[number].cont_name, ch, 8);
-
- key_rects[number].cont_name[8] = '\0';
-
- number++;
- }
-
- /////////////////////////////
- int OutputWindow::on_special() // number of context
- {
- int n = 0;
- while(!key_rects[n].ltrb.contains(curs) && n < number)
- n++;
- if(n == number) return 0;
-
- int m = 0;
- while(strcmp(key_rects[n].cont_name, contexts[m].cont_name))
- {
- if(contexts[m].cont_name[0] == '\0')
- return 0;
- m++;
- }
- return m + 1;
- }
- /////////////////////////////
- void OutputWindow::jmp_to(char* context)
- {
- rect r = user_screen();
- int m = 0;
- while(strcmp(context, contexts[m].cont_name))
- {
- if(contexts[m].cont_name[0] == '\0')
- return;
- m++; // context number
- }
- if(m + 1) // number of context + 1
- {
- pages[0] = contexts[m].page;
- file_position = pages[pages[0]];
- start.Y = contexts[m].line;
- start.X = 0;
- }
- }
- ////////////////////////////////////
- void prev_stek::add(loc page_line)
- {
- if(used < previous_num - 1)
- { used++; previous[used] = page_line; }
- else
- {
- for(int i = 0; i < previous_num - 1; i++)
- previous[i] = previous[i + 1];
- used = i;
- previous[used] = page_line;
- }
- }
-